// Copyright (c) 2021 Presto Labs Pte. Ltd.
// Author: daniel

#pragma once

#include <memory>
#include <string>
#include <unordered_map>

#include "coin2/exchange/base/order/order.h"
#include "coin2/exchange/order/gateio.pb.h"
namespace coin2::exchange::gateio::api_order {

enum GateioOrderSubTopicId : int {
  REST_DEPOSIT = 10000,
  REST_WITHDRAWAL = 10001,
  REST_TRANSFERS = 10002
};

}  // namespace coin2::exchange::gateio::api_order

class GateioNativePrivateClient : public coin2::exchange::base::order::NativePrivateClient {
 public:
  using RestParams = coin2::exchange::order::GateioRestParams;
  using NativeClientConfig = coin2::exchange::order::OrderConnectionConfig;
  using HttpContextPtr = std::shared_ptr<AsioHttpContext>;
  using AsioHttpContextList = std::list<std::shared_ptr<AsioHttpContext>>;

 public:
  std::shared_ptr<AsioHttpContext> SubmitOrderExecution(const OrderExecutionProto& order);
  std::shared_ptr<AsioHttpContext> SubmitRestQuery(const RestQueryProto& query);
  AsioHttpContextList SubmitRestQueryList(const RestQueryProto& query);

 public:
  explicit GateioNativePrivateClient(
      const MarketExchangeApi& mea,
      const NativeClientConfig& config);

  HttpContextPtr QueryAccountBalance();
  HttpContextPtr QueryOpenOrders(const RestParams& params);
  HttpContextPtr QueryHistOrders(const RestParams& params);
  HttpContextPtr QueryHistTrades(const RestParams& params);

  HttpContextPtr PlaceSingleOrder(const RestParams& params);
  HttpContextPtr PlaceBatchOrders(const std::vector<RestParams>& params);
  HttpContextPtr CancelSingleOrder(const RestParams& params);
  HttpContextPtr CancelBatchOrders(const std::vector<RestParams>& params);
  HttpContextPtr PlaceOrderNorm(const OrderExecution&) override;
  HttpContextPtr CancelOrderNorm(const OrderExecution&) override;

  HttpContextPtr QueryDeposit(const RestParams& params);
  HttpContextPtr QueryWithdrawal(const RestParams& params);
  HttpContextPtr QueryTransfers(const RestParams& params);

  RestParams GetRestOrderParams(const OrderSpec& order_spec, int64_t proc_order_id);
  RestParams GetRestCancelParams(const IOrderContext& order_context);

  std::string DebugString() const;
  bool IsMasterAccount() const;

 private:
  int64_t start_time_;
  std::unordered_map<std::string, int32_t> api_block_info_;
  std::unordered_map<std::string, int32_t> api_req_info_;

 private:
  const std::string path_query_account_balance_ = "/api/v4/spot/accounts";
  const std::string path_query_open_orders_ = "/api/v4/spot/open_orders";
  const std::string path_query_hist_orders_ = "/api/v4/spot/orders";
  const std::string path_query_hist_trades_ = "/api/v4/spot/my_trades";
  const std::string path_place_single_order_ = "/api/v4/spot/orders";
  const std::string path_place_batch_orders_ = "/api/v4/spot/batch_orders";
  const std::string path_cancel_single_order_ = "/api/v4/spot/orders";
  const std::string path_cancel_batch_orders_ = "/api/v4/spot/cancel_batch_orders";
  const std::string path_query_deposit_ = "/api/v4/wallet/deposits";
  const std::string path_query_withdrawal_ = "/api/v4/wallet/withdrawals";
  const std::string path_query_transfers = "/api/v4/wallet/sub_account_transfers";

  // https://www.gate.io/docs/developers/apiv4/
};
